跳到主要内容

Go 发送邮件

官方提供了 smtp 包用来发送邮件

package main

import (
"log"
"net/smtp"
)

func main() {
// Set up authentication information.
auth := smtp.PlainAuth("", "user@example.com", "password", "mail.example.com")

// Connect to the server, authenticate, set the sender and recipient,
// and send the email all in one step.
to := []string{"recipient@example.net"}
msg := []byte("To: recipient@example.net\r\n" +
"Subject: discount Gophers!\r\n" +
"\r\n" +
"This is the email body.\r\n")
err := smtp.SendMail("mail.example.com:25", auth, "sender@example.org", to, msg)
if err != nil {
log.Fatal(err)
}
}

简单使用

简单使用例,封装一个发送邮件的功能

func SendToMail(user, sendUserName, password, host, to, subject, body, mailtype string) error {
hp := strings.Split(host, ":")
auth := smtp.PlainAuth("", user, password, hp[0])
var content_type string
if mailtype == "html" {
content_type = "Content-Type: text/" + mailtype + "; charset=UTF-8"
} else {
content_type = "Content-Type: text/plain" + "; charset=UTF-8"
}

msg := []byte("To: " + to + "\r\nFrom: " + sendUserName + "<" + user + ">" + "\r\nSubject: " + subject + "\r\n" + content_type + "\r\n\r\n" + body)
send_to := strings.Split(to, ";")
err := smtp.SendMail(host, auth, user, send_to, msg)
return err
}

使用例:

func main() {
useremail := "用户邮箱"
password := "用户密码"
host := "smtpdm.aliyun.com:80"
to := "目标邮箱"

subject := "使用Golang发送邮件"

body := `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="iso-8859-15">
<title>标题</title>
</head>
<body>
GO 发送邮件,官方连包都帮我们写好了,真是贴心啊!!!
</body>
</html>`

sendUserName := "GOLANG SEND MAIL" //发送邮件的人名称
fmt.Println("send email")
err := SendToMail(useremail, sendUserName, password, host, to, subject, body, "html")

if err != nil {
fmt.Println("Send mail error!")
fmt.Println(err)
} else {
fmt.Println("Send mail success!")
}
}

TLS 问题

func SendMailUsingTLS(addr string, auth smtp.Auth, from string,
to []string, msg []byte) (err error) {
log.Debugf("start SendMailUsingTLS... \n")
//create smtp client
c, err := Dial(addr)
if err != nil {
log.Errorf("Create smtp client error: %s \n", err)
return err
}

defer c.Close()
if auth != nil {
if ok, _ := c.Extension("AUTH"); ok {
if err = c.Auth(auth); err != nil {
log.Errorf("Error during AUTH: \n", err)
return err
}
}
}
if err = c.Mail(from); err != nil {
log.Errorf("Mail error: %s \n", err)
return err
}

for _, addr := range to {
if err = c.Rcpt(addr); err != nil {
log.Errorf("Mail error: %s \n", err)
return err
}
}

w, err := c.Data()
if err != nil {
log.Errorf("Mail error: %s \n", err)
return err
}

_, err = w.Write(msg)
if err != nil {
log.Errorf("Mail error: %s \n", err)
return err
}

err = w.Close()
if err != nil {
log.Errorf("Mail error: %s \n", err)
return err
}
return c.Quit()
}

func Dial(addr string) (*smtp.Client, error) {
conn, err := tls.Dial("tcp", addr, nil)
// conn, err := tls.Dial("tcp", addr, &tls.Config{InsecureSkipVerify:true})
if err != nil {
log.Errorf("Dialing Error: %s \n", err)
return nil, err
}

//分解主机端口字符串
host, _, _ := net.SplitHostPort(addr)
return smtp.NewClient(conn, host)
}